<?php 
//ArrowController::importModel("org.arrowplatform.interfaces.IArrowSingleton");
class ArrowCtrlStateManager implements IArrowSingleton{
	
	const URL_PARAMETER = "ctrlstate";
	
	private static $oInstance;
	/**
	 * @return ArrowCtrlStateManager
	 */
	public static function getDefault(){
		if( self::$oInstance == null )
			self::$oInstance = new ArrowCtrlStateManager();
		return self::$oInstance;
	}
	
	private $currUrl;
	private $data = array();
	
	public function __construct(){
		$rq = ArrowRequestContext::getDefault();
		$this->currUrl = $_SERVER["REQUEST_URI"];
		if($rq[self::URL_PARAMETER])
			$this->data = $this->unserialize($rq[self::URL_PARAMETER]); 
			
	}
	
	private function unserialize( $string ){
		$data = array();
		$main = explode( "||", urldecode($string) );
		array_shift($main);
		
		for($i=0;$i<count($main);$i+=2){
			if(isset($main[$i+1])){
				$local = explode( "|", $main[$i+1] );
				for($j=0;$j<count($local);$j+=2){
					$data[$main[$i]][$local[$j]] = $local[$j+1];
				}
			} 			
		}
		return $data;
	}
	
	private function serialize($data){
		$str = "";
		foreach($data as $controlId=>$values){
			$str.="||".$controlId."|";
			foreach( $values as $key => $value ){
				$str.="|".$key."|".$value;
			}
		}
		return $str;
	}
	
	public function setState( ArrowNode $control, $name, $value ){
		if($value=="")
			$value="_empty_";
		$this->data[$control->getGlobalId()][$name] = $value;
	}
	
	public function getState( ArrowNode $control, $name ){
		if(!isset($this->data[$control->getGlobalId()][$name]) || $this->data[$control->getGlobalId()][$name] == "_empty_")
			return null;
		return $this->data[$control->getGlobalId()][$name];
	}
	
	/**
	 * Returns contrlol state change url
	 * @param ArrowNode $control
	 * @param unknown_type $parameters
	 */
	public function getStateChangeLink( ArrowNode $control, $parameters, $forceUrl = false, $encode = true  ){
		$data = $this->data;
		
		foreach($data as $data_key => $data_item)
			foreach($data_item as $key => $item)
				$data[$data_key][$key] = urlencode($item);
		
		foreach( $parameters as $param=>$value ){
			if($encode)
				$value = urlencode($value);
			if($value=="")
				$value="_empty_";
				
			$data[$control->getGlobalId()][$param] = $value;
		}
		
		$url = $this->currUrl;
		$href = $this->addUrlParam( $url, array(
				self::URL_PARAMETER => $this->serialize($data),
		));
	
		if( $ajax = $control->getParent("ArrowCtrlAjax") ){
			$href = $this->addUrlParam( $href, array(
				ArrowRouter::CONTROLL_REQUEST_PARAMETER => 1,
				ArrowNode::CTRL_NAMESPACE."-ctrlId" =>  $control->getId(),
				ArrowNode::CTRL_NAMESPACE."-ctrlGlobalId" =>  $control->getGlobalId()
			));
			if($forceUrl)
				return $href;
			return "javascript: CtrlAjax.changeState('{$ajax->getId()}', '$href');";
		} 

		return $href;
	}
	
	public static function addUrlParam( $url, $parameters ){
		foreach( $parameters as $param=>$value ){
			$pos = strpos($url, $param);
			if( $pos !== false ){
				$end = strpos($url, "&", $pos);
				if($end>0){
					$index = $pos+1+strlen($param);
					$url = substr_replace( $url, $value, $pos+1+strlen($param), $end-$index );
				}else{ 
					$url = substr_replace( $url, $value, $pos+1+strlen($param) );
				}
			}else
				$url = $url.((strpos($url,"?") === false)?"?":"&").$param.'='.$value;
		}
		return $url;
	}
	
}
?>